(* 
 -,! negative, not operator
 +,-,*,/ arithmetic operators between signed integers
 >,<,>=,<=,!=,== boolean operators of signed integers
*)

(* unary operator for interger *)
type intop1 = 
	|Neg (* - :1->-1, -1->1 *)
	|Not (* ! :0->1 ,  1->0 *)

(* binary operator for interger *)
type intop2 = 
	|Add (* + *)
	|Sub (* - *)
	|Mul (* * *)
	|Div (* / *)
	|Mod (* % *)
	(* bash style operator name *)
	|Eq (* == EQual *)
	|Ne (* != Not Equal *)
	|Gt (* >  Greater Than *)
	|Ge (* >= Greater than or Equal to *)
	|Lt (* <  Less Than *)
	|Le (* <= Less than or Equal to *)
	(* logical operation *)
	|And (* && *)
	|Or  (* || *)

type expr =
	|Literal of int                              (* 1 *)
	|Id of string                                (* a *)
	|Binop of expr * intop2 * expr               (* a+1 *)
	|Unary of intop1 * expr                      (* -a *)
	|Assign of string * expr                     (* a=1 *)
	|Call of string * expr list                  (* foo(a) *)

type stmt=
	|Block of stmt list
	|Expr of expr            
	|Return of expr
	|If of expr * stmt * stmt
	|For of expr * expr * stmt
	|While of expr * stmt
	|Init of string * string * expr list           (* circle c1(a,5) *)
	|BuildinCall of string * string * expr list    (* mouse.foo(a) *)

type func_decl = {
	fname : string;
	formals : string list;
	locals : string list;
	body : stmt list;
}

type program = func_decl list * stmt list

